//
//  CTVChannelMenuController.m
//  Channltv
//
//  Created by Bruno Keymolen on 07/09/07.
//  Copyright 2007 channl.tv All rights reserved.
//

#import "CTVChannelMenuController.h"
#import "CTVCache.h"
#import "CTVMediaAsset.h"
#import "CTVMediaDownloadController.h"
#import "CTVUtil.h"
#import "CTVClipMenuItemLayer.h"
#import "CTVChannelPlayerController.h"
#import "CTVAutoUpdate.h"
#import "CTVAutoUpdateController.h"
#import "CTVIconPreviewController.h"

@implementation CTVChannelMenuController

- (id) initWithScene: (BRRenderScene *) scene andChannel:(CTVChannel*)channel{

	NSLog(@"CTVChannelMenuController - initWithScene");

	if( [super initWithScene: scene] == nil ){
        return ( nil );
	}

	
	/* Use variable row height instead of default */			
	BRMenuListLayer* listLayer = [[self list] layer];
	[listLayer setUsesVariableHeightRows:TRUE];
	[listLayer setDisplaysSelectionWidget:TRUE]; //Set the (lozenge) blue selection rectangle Off/On	
	

	//Init
	[channel retain];
	m_channel = channel;	


	//Set a play channel option
	if([[[CTVUtil userDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		[[self list] setDividerIndex:1];
	}
	
			
	[self setListTitle: [channel name]];	
	[self setPreSelectedIndex];

	
	//Title Icon
	if([channel thumbUrl]){	
		NSString* cachePath = [CTVCache getResourceCachePathForURL:[channel thumbUrl]];
		BRTexture * tex = [CTVCache createBitmapTextureFromPath:cachePath withScene:[self scene]];	
		[self setListIcon:tex];
	}

	m_previousRow = -1;


	//Calculate the height of our items
	m_clipRowItemHeight = 39.0f * 3.0f;	

	 // initialize your resources here
	[[self list] setDatasource: self];


//	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
//		[(BRListControl*)[self list] setSelection:1];
//	}

	return self;
}



- (void) dealloc
{

	NSLog(@"CTVChannelMenuController - dealloc");

	[m_channel release];
	
	

	[super dealloc];
}


- (NSRect)previewFrameForBounds:(NSSize)fp8{
	NSRect bounds = [super previewFrameForBounds:fp8];
	return bounds;
}


- (long) itemCount
{
	long count = [ [m_channel clips] count];
    // return the number of items in your menu list here
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		count++;
	}
	
	return ( count );
}


- (id)popAnimation{
	return [super popAnimation];
}


- (id)pushAnimation{
	return [super pushAnimation];
}


- (id<BRMenuItemLayer>) itemForRow: (long) row
{
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		if(row == 0){
			id result = [BRAdornedMenuItemLayer adornedMenuItemWithScene: [self scene]];
			[[result textItem] setTitle: @"Play Channel"];
			return result;
		}
		row--;
	}

    // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
    // return that object, it will be used to display the list item.
	if ( row >= [[m_channel clips] count] || row < 0){
			return ( nil );
	}
	
	
	
	CTVClipMenuItemLayer* result;

	CTVClip* clip = [[m_channel clips] objectAtIndex:row]; 
	
	if([clip menuItemLayer] == nil){
		if([clip thumbTexture] == nil){
			[clip loadBitmapTextureForScene:[self scene]];
		}
		result = [[CTVClipMenuItemLayer alloc] initWithScene:[self scene] andThumbTexture:[clip thumbTexture] andRowHeight:m_clipRowItemHeight andTitle:[clip getTitle] andRate:[clip rate]];

		[clip setMenuItemLayer:result];
		
		[result release];
	}
	
	result = [clip menuItemLayer];  
			  
	//Is cached ?
	if([[CTVCache GetInstance] isMediaInCacheForURLString:[clip getUrl]]){
		[result setClipOnDisk:TRUE];
	}else{
		[result setClipOnDisk:FALSE];
	}
	//Stream it from the net ?
	if([clip streamMedia] == TRUE){
		[result setClipStream:TRUE];
	}else{
		[result setClipStream:FALSE];
	}
	//Rate
	[result setRate:[clip rate]];
			
	//Watchpoint
	[result setWatchPoint:-1.0f];
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		if([[[m_channel watchPoint] clipID] isEqualToString:[clip clipID]]){
			[result setWatchPoint:[[m_channel watchPoint] offset]];
		}
	}
		  	  
	//Are we currently downloading this URL ?
	CTVHTTPMediaDownload* download = [[CTVCache GetInstance] isDownloadingURLString:[clip getUrl]];
	if(download != nil){
		//We need to listen for the finish event so we can stop the spinner
		[download addDownloadUpdate:(CTVMediaDownloadUpdate*)self];
		[[result textItem] setWaitSpinnerActive:TRUE];		
	}else{
		[[result textItem] setWaitSpinnerActive:FALSE];		
	}
	
				
	return ( result );
}




- (NSString *) titleForRow: (long) row
{
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		if(row == 0){
			return @"Play Channel";
		}
		row--;
	}

    if ( row >= [[m_channel clips] count] )
		return ( nil );
	
	CTVClip* clip = [[m_channel clips] objectAtIndex:row]; 

	return ( [clip getTitle] );
}


- (long) rowForTitle: (NSString *) title
{
    long result = -1;
    long i, count = [self itemCount];
    for ( i = 0; i < count; i++ )
    {
        if ( [title isEqualToString: [self titleForRow: i]] )
        {
            result = i;
            break;
        }
    }
    
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		result++;
	}
	
    return ( result );
}



- (void) itemSelected: (long) row{

	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		if(row == 0){
			//Play Clip
			CTVClip* clip = [m_channel currentClipToPlay]; 
			id controller = [[[CTVChannelPlayerController alloc] initWithScene:[self scene] forChannel:m_channel startWithClip:clip] autorelease];
			[[self stack] pushController:controller];
			[controller playClip];
			return;
		}
		row--;
	}


    if ( row >= [[m_channel clips] count] )
		return;
	
	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
	
	
	CTVClip* clip = [[m_channel clips] objectAtIndex:row]; 
	
	NSString* urlString=[clip getUrl];


	NSLog( @"Play URL: [%s]\n", [urlString UTF8String]);

	//Play Clip
	id controller = [[[CTVChannelPlayerController alloc] initWithScene:[self scene] forChannel:m_channel startWithClip:clip] autorelease];
	[[self stack] pushController:controller];
	[controller playClip];


	
//	NSString* cahcheEntry = [CTVCache getMediaCacheEntryForURL:urlString];		
//						
//	if(cahcheEntry != nil || [clip streamMedia] == TRUE ){
//
//		//Clip is in Cache or Stream content
//		id controller = [[[CTVChannelPlayerController alloc] initWithScene:[self scene] forChannel:m_channel startWithClip:clip] autorelease];
//		[[self stack] pushController:controller];
//		[controller playClip];
//	}else{
//		//Download mode: load clip to cache; show download page
//		NSString* cachePath;
//		CTVHTTPMediaDownload* downloader = [[CTVCache GetInstance] cacheURLString:urlString cachePathNoExt:&cachePath andClip:clip];
//		
//		CGImageRef img = [[CTVCache GetInstance] CreateImageForURLString:[clip getThumbUrl]];
//		if(img == nil && [clip getThumbUrl] != nil){
//			img = (CGImageRef)CreateImageForURL( [clip getThumbUrl] );
//		}
//		
//		id controller = [[[CTVMediaDownloadController alloc] initWithScene:[self scene] andClip:clip andImage:img andMediaDownload:downloader andTitle:[clip getTitle] forChannel:m_channel ] autorelease];
//		[[self stack] pushController:controller];
//	}
	
	[pool release];
}



- (id<BRMediaPreviewController>) previewControllerForItem:(long)row{
	if([[[NSUserDefaults standardUserDefaults] objectForKey:CTVCONF_CHANNELVIEW] isEqualToString:@"Yes"] ){
		if(row == 0){
			CTVIconPreviewController* iconPreview;
			NSString* path = [m_channel thumbUrl];
			CGImageRef image = [[CTVCache GetInstance] CreateImageForURLString:path];
				
			if(image != nil){
				iconPreview = [[[CTVIconPreviewController alloc] initWithScene:[self scene] andImage:image ] autorelease];
				CFRelease( image );
				return ( iconPreview );
			}

			return nil;
		}
		row--;
	}

    if ( row >= [[m_channel clips] count] ){
		return ( nil );
	}
	
	CTVClip* clip = [[m_channel clips] objectAtIndex:row]; 


	CTVMediaAsset* myAsset;
	
	myAsset = [[[CTVMediaAsset alloc] init] autorelease];
	NSString* msg = [clip getInfo];
	
	CGImageRef image;
	NSURL* url = [NSURL URLWithString:[clip getThumbUrl]];
	
	//Is in cache ?
	image = [[CTVCache GetInstance] CreateImageForURLString:[clip getThumbUrl]];
	if(image == nil){
		if(url != nil){
			image = (CGImageRef)CreateImageForURL( url );
		}
	}else{
		NSLog( @"Image from cache : %s" , [[clip getThumbUrl] UTF8String]);
	}		
		
	[myAsset setDescription:msg];
	[myAsset setTitle: [clip getTitle] ];
	[myAsset setCoverArt:image];
	[myAsset setLocal:FALSE];
	[myAsset setDuration:[clip getDuration]];
	[myAsset setMediaUrl:url];

	BRMetadataPreviewController* metaPreview = [[[BRMetadataPreviewController alloc] initWithScene:[self scene]] autorelease];
	[metaPreview setAsset:myAsset];
	if(m_previousRow == row){
		[metaPreview setShowsMetadataImmediately:TRUE];
	}else{
		[metaPreview setShowsMetadataImmediately:FALSE];
	}
	[metaPreview setDeletterboxAssetArtwork:TRUE];
	[metaPreview setBlocksDuringAnimation:TRUE];
		
	m_previousRow = row;
	
			
	return ( metaPreview );
	

}

/*
 * CTVMediaDownloadUpdate
 */
-(void)downloadPercent:(int)pc{
	//Nothing
}

-(void)downloadTimeLeft:(int)tl{
	//Nothing
}

-(void)downloadFinish{
	//Update menu (download spinner)

	//Still did not found a cleaner way to force a redraw of the menuitems
	NSArray* co = [self controls];
	int a;
	for(a=0;a<[co count];a++){
		BRControl* bc = [co objectAtIndex:a];
		[[bc layer] reload]; 
	}
	[[self scene] renderScene];
}

-(void)downloadError:(int)errorcode{
	//Update menu (download spinner)

	//Still did not found a cleaner way to force a redraw of the menuitems
	NSArray* co = [self controls];
	int a;
	for(a=0;a<[co count];a++){
		BRControl* bc = [co objectAtIndex:a];
		[[bc layer] reload]; 
	}
	[[self scene] renderScene];
	NSLog(@"Error downloading file:%d", errorcode);
}


/*
 * CTVSyncListener
 */
-(void)syncStarted{
}

-(void)syncStopped{
	//Some control for our selection selector 
	long row = [(BRListControl*)[self list] selection];
	long max = 0.0 + [[m_channel clips] count];
	if ( row >= max ){
		[(BRListControl*)[self list] setSelection:max-1];		
	}

	//Redraw menu - clip update
	[self resetLayout];
	[self refreshControllerForModelUpdate]; //Needed to get an eventually new preview

				
	//Still did not found a cleaner way to force a redraw of the menuitems
	NSArray* co = [self controls];
	int a;
	for(a=0;a<[co count];a++){
		BRControl* bc = [co objectAtIndex:a];
		[[bc layer] reload]; 
	}	
	[[self scene] renderScene]; 		
}


//Called after the sync process but before existing clips/channels are deleted from mem
-(void)syncWillFinish{ 
	//Check if our channel will be deleted. if so; remove this menu and go one step back
	if([m_channel willBeDeleted] == TRUE){
		//Remove this screen, go back in the menu tree
		[[self stack] removeController:self];
	}
}



//Controller will be displayed on screen 
- (void)willBePushed{
	//Subscribe for sync events (menu updates)
	[[CTVSync GetInstance] addListener:(CTVSyncListener*)self];

	[super willBePushed];
}


//Controller will be taken from screen
- (void)willBePopped{
	//Unsubscribe for sync events
	[[CTVSync GetInstance] removeListener:(CTVSyncListener*)self];

	[super willBePopped];
}

- (void)wasExhumedByPoppingController:(id)fp8{
	[super wasExhumedByPoppingController:fp8];	
}


//NSObject
- (id)retain{
	return [super retain];
}


- (oneway void)release{
	[super release];
}


- (id)autorelease{
	return [super autorelease];
}


- (unsigned)retainCount{
	return [super retainCount];
}


@end
